
#include <string.h>
#include <CoOS.h>			 			/*!< CooCox RTOS header file.		  */

#include "NUC1xx.h"
#include "ir_remo_ctrl.h"

#include "Driver\DrvSYS.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvFMC.h"

#include "usb_vcom.h"

#include "temperature.h"
#include "flash_param.h"

#define MAX_FLASH_ADDRESS	(0x00020000)

uint32_t g_next_save_add = 0;

SCALE_T g_scale[MAX_CHANNEL] = {
//	ch, t_on, 	k*16, s, p, 	q
	{0,	28, 	0x18, 4, 34, 	-900},
	{1,	28, 	0x18, 4, 34, 	-900},
//	{2,	28, 	0x18, 4, 34, 	-900},
//	{3,	28, 	0x18, 4, 34, 	-900},
};


void flash_config(void)
{
	

}

void load_scales(void)
{
// definitions
	uint32_t ptr = 0;
	uint32_t data = 0xFFFFFFFF;

	SCALE_T scale;

// code
	CoSchedLock();
	UNLOCKREG();
	DrvFMC_EnableISP();
	ptr = DrvFMC_ReadDataFlashBaseAddr();
//	LOCKREG();

	for (; ptr < MAX_FLASH_ADDRESS; )
	{
//		UNLOCKREG();
		DrvFMC_Read(ptr, &data);
		if (0xFFFFFFFF == data)	break;
		ptr += 4;
		*(uint32_t*)(&scale) = data;
		DrvFMC_Read(ptr, &data);
		ptr +=4;
		*((uint32_t*)(&scale)+1) =  data;

		memcpy(g_scale + scale.ch, &scale, sizeof(SCALE_T));
//		LOCKREG();
	}
	g_next_save_add = ptr;
	DrvFMC_DisableISP();
	LOCKREG();
	CoSchedUnlock();
}

void read_all_parameter(uint8_t channel, param_t param)
{
// definitions
	uint32_t ptr = 0;
	uint32_t data = 0xFFFFFFFF;

	SCALE_T scale;

// code
	UNLOCKREG();
	DrvFMC_EnableISP();
	ptr = DrvFMC_ReadDataFlashBaseAddr();
	LOCKREG();

	for (; ptr < MAX_FLASH_ADDRESS; )
	{
		UNLOCKREG();
		DrvFMC_Read(ptr, &data);
		if (0xFFFFFFFF == data)	break;
		ptr += 4;
		*(uint32_t*)(&scale) = data;
		DrvFMC_Read(ptr, &data);
		ptr +=4;
		*((uint32_t*)(&scale)+1) =  data;
		LOCKREG();

		usb_printf("ch: %d\r\n", scale.ch);
//		CoTickDelay(5);		//<DEBUG> 50ms, To avoid missing print data
		usb_printf("s=%d, p=%d, q=%d\r\n", scale.s, scale.p, scale.q);
//		CoTickDelay(5);		//<DEBUG> 50ms, To avoid missing print data
		usb_printf("t_on=%d, k=0x%02X\r\n", scale.t_on, scale.k);
//		CoTickDelay(5);		//<DEBUG> 50ms, To avoid missing print data
	}
//	g_next_save_add = ptr;
	usb_printf("next add = 0x%08X\r\n", ptr);
	usb_printf("g_next_save_add = 0x%08X\r\n", g_next_save_add);
	DrvFMC_DisableISP();
	LOCKREG();
}

void reset_all_scale(uint8_t channel, param_t param)
{
	uint32_t base;

	UNLOCKREG();
	DrvFMC_EnableISP();
	base = DrvFMC_ReadDataFlashBaseAddr();
	while (base < MAX_FLASH_ADDRESS)
	{
		DrvFMC_Erase(base);
		base += 512;
	}
	g_next_save_add = DrvFMC_ReadDataFlashBaseAddr();
	DrvFMC_DisableISP();
	LOCKREG();

	usb_printf("all scales are erased.\r\n");
}

void save_parameter(uint8_t channel, param_t param)
{
	uint32_t base;
	SCALE_T * scale = g_scale + channel;
	uint32_t * p_scale = (uint32_t*) (scale);

	if (channel > MAX_CHANNEL)
	{
		usb_printf("!01 illeagle channel\r\n");
		return;
	}

	UNLOCKREG();
	DrvFMC_EnableISP();

	if (g_next_save_add > MAX_FLASH_ADDRESS)
	{	// Erase data and save
		base = DrvFMC_ReadDataFlashBaseAddr();
		g_next_save_add = base;
		while (base < MAX_FLASH_ADDRESS)
		{
			DrvFMC_Erase(base);
			base += 512;
		}
	}

	DrvFMC_Write(g_next_save_add, p_scale[0]);
	g_next_save_add += 4;
	DrvFMC_Write(g_next_save_add, p_scale[1]);
	g_next_save_add += 4;

	DrvFMC_DisableISP();
	LOCKREG();

	usb_printf("channel %d saved.\r\n", channel);
}

void set_parameter_temp(uint8_t channel, param_t param)
{
	uint16_t p;
	SCALE_T * scale = g_scale + channel;

	if (channel > MAX_CHANNEL)
	{
		usb_printf("!01 illeagle channel\r\n");
		return;
	}
	p = (int16_t)( (param >> 16) & 0xFFF);
	if ( p & 0x800) p |= 0xF000;
	scale->p = p;
	scale->q = (int16_t)( param & 0xFFFF);
	scale->s = (uint8_t)( (param >> 28) & 0xF);
	usb_printf("%d, %d, %d\r\n", scale->s, scale->p, scale->q);
//	SaveParameter(0);
}

void set_parameter_fan(uint8_t channel, param_t param)
{
	SCALE_T * scale = g_scale + channel;

	if (channel > MAX_CHANNEL)
	{
		usb_printf("!01 illeagle channel\r\n");
		return;
	}

	scale->t_on = (param >> 8) & 0xFF;
	scale->k = ( param & 0xFF);
	usb_printf("%d, 0x%02X\r\n", scale->t_on, scale->k);
//	SaveParameter(0);
}

void read_parameter(uint8_t channel, param_t param)
{
	SCALE_T * scale = g_scale + channel;
	if (channel > MAX_CHANNEL)
	{
		usb_printf("!01 illeagle channel\r\n");
		return;
	}

	usb_printf("s=%d, p=%d, q=%d\r\n", scale->s, scale->p, scale->q);
	CoTickDelay(5);		//<DEBUG> 50ms, To avoid missing print data
	usb_printf("t_on=%d, k=0x%02X\r\n", scale->t_on, scale->k);
}
